package game;

import java.io.*;
import java.util.ArrayList;

public class TextManager {

    public static ArrayList<Textos> textos;
    //Configurations.LANGUAGE is the current text

    public static class Textos implements Serializable {
        private static final long serialVersionUID = 1L;

        public String NAME;
        public String[] UPGRADES_NAMES, SHIPS, SHIPS_DESCRIPTION, MENU_OPTIONS, NEW_GAME;
        public String[][] ATTRIBUTES;
        public String[] ATT_DES;
        public String[] ITEM_CATEGORIES;
        public String ALL_ITEMS, EQUIPS, UPGRADES, NO_ITEM;
        public String MENU_NAME;
        public String[][] MENU_ITEMS;
        public String[] MENU_ACTIONS;
        public String[] EQUIPS_NAMES;
        //texts related to item naming
        public String[] PARTS;
        public String CONDITIONS_NAMES, EFFECTS_NAMES;
        public String[][] INV_MENUS_NAMES, INV_MENUS_DESC;
        public String AMMO_NAME, AMMO_DESC;
        
        public String[] INV_ERRORS;

        public static Textos getEnglish() {
            Textos t = new Textos();
            t.NAME = "Terent";
            t.ATTRIBUTES = new String[][] {
                {"Life", "Electricity Resistance", "Heat Resistance"},
                {"Energy", "Movement Energy", "Upgrades Energy"},
                {"Offense", "Energy Based", "Projectile Based"},
                {"Defense", "Explosion Resistance", "Impact Resistance"},
                {"Speed", "Linear Acceleration", "Angular Speed"},
                {"Cargo", "Volume Limitations", "Mass Limitations"}
            };
            t.ATT_DES = new String[] {
                "Your current $att is $value / $(total).", //life and energy
                "This gives you @eval($value %* 100)% of $(att).", //resistences (life and def)
                "This gives you @eval($value %* 100)% of $att attacks bonus.", //offense
                "This gives you @eval($value %* 100)% of reduction on $att consuption.", //energy
                "This gives you $value $unit of $(att)." //speed
            };
            t.UPGRADES_NAMES = new String[]{"Main Laser", "Secondary Laser", "Machine Gun", "Missile Launcher", "Singularity Cargo" , "Illumination Panel" , "Magnet", "Bombs Dispenser", "Hook", "Bottom Laser", "Gravity Center", "Bomb Charger with CG", "Heat Ray", "Cold Ray", "Turbo", "Air Propeller", "Radar Invisibility", "Fission Energy Generator", "Ultra Laser", "Electrical Discharge", "EMP"};
            t.SHIPS = new String[]{"Ship", "Offensive", "Defensive", "Trader"};
            t.SHIPS_DESCRIPTION = new String[]{"This ship has more Attack and Energy than the others; it it's, thus, focused in Attack.", "This ship has more Defensive and Life than the others. It is, thus, focused in Defense.", "This ship has more Speed and Cargo than the others; it is, thus, focused in trading and stealth."};
            t.MENU_OPTIONS = new String[]{"Play", "Extras", "Options", "Exit"};
            t.NEW_GAME = new String[]{"Choose your name", "Name:", "Choose your initial ship", "New game..."};
            t.ITEM_CATEGORIES = new String[]{"Consumables", "Equips", "Ammunition", "Books", "Keys", "Materials", "Misc"};
            t.PARTS = new String[]{"Body", "Wing", "Back Prop.", "Side Prop.", "Energy Transformer"};
            t.ALL_ITEMS = "All items";
            t.EQUIPS = "Equiped";
            t.UPGRADES = "Upgrades";
            t.NO_ITEM = "No item found.";

            t.MENU_NAME = "Menu";
            t.MENU_ITEMS = new String[][]{{"Status", "Inventory", "Journal", "Maps", "System"}, {"Save", "Load", "Options", "Exit"}, {"Current area", "Current system", "Galaxy", "Search"}, {"Quests", "Dialogs", "Contacts", "Log"}};
            t.MENU_ACTIONS = new String[]{"Go back", "Select", "Use item", "Quick Access"};

            //#cond (Condicao[])
            t.CONDITIONS_NAMES = "@if(#cond[] %> 0){Requires: @for(%i = 0, #cond[] %- 1){#cond[%i], }#cond[#cond[] %- 1].}";
            
            //#e (Efeito[])
            t.EFFECTS_NAMES = "@if(#e[] %> 0){Gives: @for(%i = 0, #e[] %- 1){#e[%i], }#e[#e[] %- 1].}";
            
            //EQUIPS_NAMES[name / desc]
            //#part, $material, $plating, #type
            t.EQUIPS_NAMES = new String[] {"$material @if($plating %!= $material){$(plating)-plated }#part[0]", "A simple $material @if($plating %!= $material){$(plating)-plated }#part[0]. It works on #type[0]@if(#type[] %> 1){@for(%i = 1, #type[] %- 1){, #type[%i]} and #type[#type[] %- 1]} ships.@if(#part[] %> 1){ It also has a #part[1]@for(%i = 2, #part[] %- 1){, a #part[%i]}@if(#part[] %> 2){ and a #part[#part[] %- 1]}.}"};
            
            //$type, $pot
            t.AMMO_NAME = "@if($type %== 0){Projectile}{@if($type %== 1){Missile}{@if($type %== 2){Bomb}{Bomb with Gravity Center}}}";
            t.AMMO_DESC = "A @if($type %== 0){projectile for the machine gun}{@if($type %== 1){missile. It explodes upon impact}{@if($type %== 2){simple bomb}{bomb with gravity center. It actually implodes}}}.";
            
            /*
             *  0: The operation will extrapolate volume limits
             *  1: Don't have the preequisits
             *  2: Don't have the item
             *  3: Can't use this kind of item
             */
            t.INV_ERRORS = new String[] {"This operation will extrapolate volume limits.", "You don't fulfill the prerequisites.", "You don't have this item.", "You can't use this kind of item."};
            
            t.INV_MENUS_NAMES = new String[][] { new String[] {"Options", "Use", "Destroy"}, new String[] {"Commerce", "Show info", "Hide info", "Lock", "Unlock", "Default Price"}, new String[]{"Quick Access"}, new String[] {"Transaction", "Add Item", "Add Money", "Commit", "Cancel", "Buy", "Sell"}, new String[] {"Ship's Offer", "Accept", "Change offer", "Deny"}};
            t.INV_MENUS_DESC = new String[][] {
                new String[] {"Consume, equip or use the selected item.", "Destroy the selected item. It will be molecular disassembled. Beware: this cannot be undone."},
                new String[] {"Show the commerce information for each item.", "Hide the commerce information in each item.", "Lock this item, so it won't be visible when trading.", "Unlock this item, so it will be visible when trading.", "The starting price of this product while selling. The buyer may try to bargain, of course."},
                new String[0],
                new String[] {"Add the selected item to this transaction.", "Add money to this transaction. Positive values means you are receiving; negative, that you are paying.", "Propose this transaction, as it is.", "Cancel the current transaction."},
                new String[] {"Accept this offer, as it is.", "Propose a change in this offer. Don't alter it too much, though - the other part may quit.", "Deny this transaction forever. Use only if you really don't want these items."}
            };

            return t;
        }

        public static Textos getPortuguese() {
            Textos t = new Textos();
            t.NAME = "Terent";
            t.ATTRIBUTES = new String[][] {
                {"Vida", "Electricity Resistance", "Heat Resistance"},
                {"Energia", "Tranformação de Energia para Movimento", "Transformação de Energia para Upgrades"},
                {"Ataque", "Ataques de Energia", "Ataques de Projétils"},
                {"Defesa", "Reistência à Explosões", "Resistência à Impactos"},
                {"Velocidade", "Aceleração Linear", "Aceleração Angular"},
                {"Capacidade de Carga", "Limitações de Volume", "Limitações de Massa"}
            };
            t.UPGRADES_NAMES = new String[]{"Main Laser", "Secondary Laser", "Machine Gun", "Missile Launcher", "Singularity Cargo" , "Illumination Panel" , "Magnet", "Bombs Dispenser", "Hook", "Bottom Laser", "Gravity Center", "Bomb Charger with CG", "Heat Ray", "Cold Ray", "Turbo", "Air Propeller", "Radar Invisibility", "Fission Energy Generator", "Ultra Laser", "Electrical Discharge", "EMP"};
            t.SHIPS = new String[]{"Nave", "Ofensiva", "Defensiva", "Comerciante"};
            t.SHIPS_DESCRIPTION = new String[]{"Essa nave possui mais ofensiva e energia que os outros modelos, sendo, portanto, voltada para o ataque.", "Essa nave possui mais defesa e vida que os outros modelos, sendo, portanto, voltada para a defesa.", "Essa nave possui mais capacidade de carga e velocidade que os outros modelos, sendo, portanto, voltada para o comércio e fugas, al�m de ataques furtivos."};
            t.MENU_OPTIONS = new String[]{"Jogar", "Extras", "Opções", "Sair"};
            t.NEW_GAME = new String[]{"Escolha seu nome", "Nome:", "Escolha sua nave inicial", "Novo jogo..."};
            t.ITEM_CATEGORIES = new String[]{"Consumíveis", "Equipamentos", "Munição", "Livros", "Chaves", "Mateirias", "Outros"};
            t.PARTS = new String[]{"Carcaça", "Asa", "Prop. Traseiro", "Prop. Lateral", "Transformador de Energia"};
            t.ALL_ITEMS = "Todos os items";
            t.EQUIPS = "Equipados";
            t.UPGRADES = "Upgrades";
            t.NO_ITEM = "Nenhum item encontrado.";

            t.MENU_NAME = "Menu";
            t.MENU_ITEMS = new String[][]{{"Status", "Inventário", "Diário", "Mapas", "Sistema"}, {"Salvar", "Carregar", "Opções", "Sair"}, {"Área atual", "Sistema atual", "Galáxia", "Procurar"}, {"Missões", "Conversas", "Contatos", "Log"}};
            t.MENU_ACTIONS = new String[]{"Voltar", "Selecionar", "Usar item", "Acesso Rápido"};

            //#cond (Condicao[])
            t.CONDITIONS_NAMES = "@if(#cond[] %> 0){Requires: @for(%i = 0, #cond[] %- 1){#cond[%i], }#cond[#cond[] %- 1].}";
            
            //#e (Efeito[])
            t.EFFECTS_NAMES = "@if(#e[] %> 0){Gives: @for(%i = 0, #e[] %- 1){#e[%i], }#e[#e[] %- 1].}";
            
            //EQUIPS_NAMES[name / desc]
            //#part, $material, $plating, #type
            t.EQUIPS_NAMES = new String[] {"$material @if($plating %!= $material){$(plating)-plated }#part[0]", "A simple $material @if($plating %!= $material){$(plating)-plated }#part[0]. It works on #type[0]@if(#type[] %> 1){@for(%i = 1, #type[] %- 1){#type[%i], } and #type[#type[] %- 1]} ships.@if(#part[] %> 1){ It also has a #part[1]@for(%i = 2, #part[] %- 1){, a #part[%i]}@if(#part[] %> 2){ and a #part[#part[] %- 1]}.}"};
            
            t.INV_ERRORS = new String[] {"This operation will extrapolate volume limits.", "You don't fulfill the prerequisites.", "You don't have this item.", "You can't use this kind of item."};
            
            t.INV_MENUS_NAMES = new String[][] { new String[] {"Options", "Use", "Destroy"}, new String[] {"Commerce", "Show info", "Hide info", "Lock", "Unlock", "Default Price"}, new String[]{"Quick Access"}, new String[] {"Transaction", "Add Item", "Add Money", "Commit", "Cancel"}};
            t.INV_MENUS_DESC = new String[][] {
                new String[] {"Consume, equip or use the selected item.", "Destroy the selected item. It will be molecular disassembled. Beware: this cannot be undone."},
                new String[] {"Show the commerce information for each item.", "Hide the commerce information in each item.", "Lock this item, so it won't be visible when trading.", "Unlock this item, so it will be visible when trading.", "The starting price of this product while selling. The buyer may try to bargain, of course."},
                new String[0],
                new String[] {"Add the selected item to this transaction.", "Add money to this transaction. Positive values means you are receiving; negative, that you are paying.", "Propose this transaction, as it is.", "Cancel the current transaction."}};
            return t;
        }
    }

    public static void load(String arquivo) {
        textos = new ArrayList<>();

        File f = new File(arquivo);
        if (f != null) { //Folder exists
            File[] fs = f.listFiles();
            for (int i = 0; i < fs.length; i++)
                try (ObjectInputStream leitor = new ObjectInputStream(new FileInputStream(fs[i]))) {
                    textos.add((Textos) leitor.readObject());
                } catch (ClassNotFoundException | IOException ex) {
                    System.err.println("Error while reading the Texts file '" + fs[i].getName() + "': " + ex.getLocalizedMessage());
                }
        }

        if (textos.isEmpty()) {
            System.out.println("Can't find language files. Creating default ones...");
            textos.add(Textos.getEnglish());
            save(0, "en_us.lan");
            textos.add(Textos.getPortuguese());
            save(1, "pt_br.lan");
        }
    }

    public static void save(int i, String arquivo) {
        try (ObjectOutputStream esc = new ObjectOutputStream(new FileOutputStream(new File("languages\\" + arquivo)))) {
            esc.writeObject(textos.get(i));
        } catch (IOException ex) {
            System.err.println("Error while writing the Texts file '" + arquivo + "': " + ex.getLocalizedMessage());
        }
    }

    public static Textos t() {
        return textos.get(Configurations.LANGUAGE);
    }
}
